import string
a = input()
if len(a) == 0:
print(0)
dp = [0] * 100000
s = 1 if a[0] not in string.ascii_uppercase else 0
for i in range(1, len(a)):
dp[i] = (dp[i - 1] if a[i] in string.ascii_lowercase else min(1 + dp[i - 1], s))
s += 1 if a[i] not in string.ascii_uppercase else 0
print(dp[len(a) - 1])
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
#define ld long double
#define all(x) x.begin(), x.end()
#define SORT(x) sort(all(x))
#define UNIQUE(x) sort(all(x)), x.erase(unique(all(x)), x.end())
#define count(s, c) count(all(s), c)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define si(c) (int)(c).size()
#define pb push_back
#define eb emplace_back
#define ff first
#define ss second
template <class T> void scan(T &a) { cin >> a; }
void IN() {}
template <class Head, class... Tail> void IN(Head &head, Tail &...tail) {
scan(head);
IN(tail...);
}
#define INT(...)\
int __VA_ARGS__;\
IN(__VA_ARGS__)
#define LL(...)\
ll __VA_ARGS__;\
IN(__VA_ARGS__)
#define STR(...)\
string __VA_ARGS__;\
IN(__VA_ARGS__)
#define CHR(...)\
char __VA_ARGS__;\
IN(__VA_ARGS__)
#define DBL(...)\
double __VA_ARGS__;\
IN(__VA_ARGS__)
#define TEST \
INT(testcases); \
while(testcases--)
#define vi vector<int>
#define vll vector<ll>
#define vpi vector<pii>
#define vpll vector<pll>
#define vec(type, name, ...) vector<type> name(__VA_ARGS__)
#define VEC(type, name, size) \
vector<type> name(size); \
IN(name)
#define vv(type, name, h, ...) vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define VV(type, name, h, w)\
vector<vector<type>> name(h, vector<type>(w)); \
IN(name)
#define vvv(type, name, h, w, ...) vector<vector<vector<type>>> name(h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...) \
vector<vector<vector<vector<type>>>> name(a, vector<vector<vector<type>>>(b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))
#define mt make_tuple
#define lb(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define ub(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define MIN(container) min_element(all(container))
#define MAX(container) max_element(all(container))
#define SUM(container) accumulate(all(container), 0ll)
template<typename T> static constexpr T inf = numeric_limits<T>::max()/2;
const double EPS = 1E-9;
const int INF = 1000000000;
const ll INF64 = (ll) 1E18;
const double PI = 3.1415926535897932384626433832795;
template<typename _Tp>
istream& operator >> (istream& i, vector<_Tp>& v){
for(_Tp& x : v)
i >> x;
return i;
}
template<class T>
vector<T>& operator -- (vector<T>& v){
for(T&x: v) --x;
return v;
}
template<class T>
vector<T>& operator ++ (vector<T>& v){
for(T&x: v) ++x;
return v;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
for(auto it = begin(v); it != end(v); ++it) {
if(it == begin(v))
os << *it;
else
os << " " << *it;
}
return os;
}
template <class T, class S> ostream &operator<<(ostream &os, const pair<T, S> &p) {
os << p.first << " " << p.second;
return os;
}
template <class T, class S> inline bool chmax(T &a, const S &b) { return (a < b ? a = b, 1 : 0); }
template <class T, class S> inline bool chmin(T &a, const S &b) { return (a > b ? a = b, 1 : 0); }
vi iota(int n) {
vi a(n);
iota(all(a), 0);
return a;
}
vector<pll> factor(ll x) {
vector<pll> ans;
for(ll i = 2; i * i <= x; i++)
if(x % i == 0) {
ans.push_back({i, 1});
while((x /= i) % i == 0) ans.back().second++;
}
if(x != 1) ans.push_back({x, 1});
return ans;
}
template <class T> vector<T> divisor(T x) {
vector<T> ans;
for(T i = 1; i * i <= x; i++)
if(x % i == 0) {
ans.pb(i);
if(i * i != x) ans.pb(x / i);
}
return ans;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
STR(s);
int n=si(s);
int cnt[n+1]={};
for(int i=0; i<n; ++i)
cnt[i+1] = cnt[i] + (s[i] >= 'A' && s[i] <= 'Z');
int ans=n;
for(int i = 0; i <= n; ++i){
int leftLower = i-cnt[i];
int rightUpper = cnt[n]-cnt[i];
ans=min(ans, leftLower + rightUpper);
}
cout << ans;
return 0;
}
1302. Deepest Leaves Sum | 1209. Remove All Adjacent Duplicates in String II |
994. Rotting Oranges | 983. Minimum Cost For Tickets |
973. K Closest Points to Origin | 969. Pancake Sorting |
967. Numbers With Same Consecutive Differences | 957. Prison Cells After N Days |
946. Validate Stack Sequences | 921. Minimum Add to Make Parentheses Valid |
881. Boats to Save People | 497. Random Point in Non-overlapping Rectangles |
528. Random Pick with Weight | 470. Implement Rand10() Using Rand7() |
866. Prime Palindrome | 1516A - Tit for Tat |
622. Design Circular Queue | 814. Binary Tree Pruning |
791. Custom Sort String | 787. Cheapest Flights Within K Stops |
779. K-th Symbol in Grammar | 701. Insert into a Binary Search Tree |
429. N-ary Tree Level Order Traversal | 739. Daily Temperatures |
647. Palindromic Substrings | 583. Delete Operation for Two Strings |
518. Coin Change 2 | 516. Longest Palindromic Subsequence |
468. Validate IP Address | 450. Delete Node in a BST |